package org.ramoths.netcom.sessions;

import org.ramoths.netcom.sessions.verrous.VrLectureInputStream;

import java.io.InputStream;

public class ThInputStreamEnvoye extends Thread
{
	private final SessionCommunication sessionComm;
	private final int idInputStream;
	private final InputStream inputStream;
	//
	private final VrLectureInputStream vrLectureInputStream;
	private boolean demandeLecture;
	private int tailleLecture;
	//
	private final SuiviFlux suiviFlux;
	
	public ThInputStreamEnvoye(SessionCommunication sessionComm, int idInputStream, InputStream inputStream, SuiviFlux vrFlux)
	{
		super.setDaemon(true);
		super.setName("TH-INPUTSTREAM-ENVOYE");
		super.setPriority(NORM_PRIORITY);
		//
		this.sessionComm = sessionComm;
		this.idInputStream = idInputStream;
		this.inputStream = inputStream;
		//
		this.vrLectureInputStream = new VrLectureInputStream();
		this.demandeLecture = false;
		this.tailleLecture = 0;
		//
		this.suiviFlux = vrFlux;
	}
	
	public void lire(int taille)
	{
		vrLectureInputStream.lock();
		try
		{
			demandeLecture = true;
			tailleLecture = taille;
			vrLectureInputStream.getConditionDemandeLecture().signal();
		}
		finally
		{
			vrLectureInputStream.unlock();
		}
	}
	
	@Override
	public void run()
	{
		byte[] tempon = null;
		int nb = 0;
		//
		while (true)
		{
			vrLectureInputStream.lock();
			try
			{
				try
				{
					while (!demandeLecture)
						vrLectureInputStream.getConditionDemandeLecture().await();
				}
				catch (InterruptedException ex)
				{
					suiviFlux.setFinFlux(new Exception("Flux interrompu!"));
					break;
				}
				demandeLecture = false;
				//
				if (tailleLecture == -1)
				{
					try
					{
						inputStream.close();
					}
					catch (Exception ex)
					{
						sessionComm.iseEnvoyerFinException(idInputStream, ex);
						suiviFlux.setFinFlux(ex);
						break;
					}
					sessionComm.iseEnvoyerFin(idInputStream);
					suiviFlux.setFinFlux(null);
					break;
				}
				//
				if (tempon == null || tempon.length < tailleLecture)
				{
					tempon = new byte[tailleLecture];
				}
				//
				try
				{
					nb = inputStream.read(tempon, 0, tailleLecture);
				}
				catch (Exception ex)
				{
					sessionComm.iseEnvoyerFinException(idInputStream, ex);
					suiviFlux.setFinFlux(ex);
					break;
				}
				if (nb == -1)
				{
					sessionComm.iseEnvoyerFin(idInputStream);
					suiviFlux.setFinFlux(null);
					break;
				}
				sessionComm.iseDonnees(idInputStream, tempon, nb);
			}
			finally
			{
				vrLectureInputStream.unlock();
			}
		}
		try
		{
			inputStream.close();
		}
		catch (Exception ex)
		{
			/* Ne rien faire */
		}
		sessionComm.iseFinInputStream(this);
	}
	
	public int getIdInputStream()
	{
		return idInputStream;
	}
}
